package com.example.lt.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.lt.constant.MessageConstants;
import com.example.lt.context.BaseContext;
import com.example.lt.entity.dto.UpdateUserDTO;
import com.example.lt.entity.queryPage.BasePage;
import com.example.lt.entity.user.Favorites;
import com.example.lt.entity.user.Model;
import com.example.lt.entity.user.UserModel;
import com.example.lt.service.user.FavoritesService;
import com.example.lt.service.user.UserService;
import com.example.lt.util.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

/**
 * @Author 小涛Tao
 * @Date: 2024/07/29/13:22
 * version 1.0 注释：用户控制层，有 【 获取个人信息、根据token获取用户信息、】 等接口
 **/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/joyfulMoments/customer")
public class CustomerController {

    private final UserService userService;

    private final FavoritesService favoritesService;

    /**
     * 用户修改信息
     * @return
     */
    @PutMapping
    public Result updateUser(@RequestBody @Validated UpdateUserDTO userDTO) {
        log.info("用户修改基本信息");
        userService.updateUser(userDTO);
        return Result.ok().message(MessageConstants.UPDATE_SUCCESS);
    }

    /**
     * 获取个人信息
     * @param userId 参数 userId
     * @return
     */
    @GetMapping("/getInfo/{userId}")
    public Result getInfo(@PathVariable("userId") Long userId) {
        log.info("根据userId获取用户信息");
        return Result.ok().data(userService.getInfo(userId));
    }

    /**
     * 根据token获取用户信息，也就是获取当前用户的信息，包括关注和粉丝列表
     * @return
     */
    @GetMapping("/getInfo")
    public Result getDefaultInfo() {
        log.info("根据token获取用户信息");
        final Long userId = BaseContext.get();
        return Result.ok().data(userService.getInfo(userId));
    }

    /**
     * 关注 或 取关
     * @param followsUserId 目标对象
     * @return
     */
    @PostMapping("/follows")
    public Result follows(@RequestParam Long followsUserId) {
        log.info("用户关注：{}", followsUserId);
        return Result.ok().message(userService.follows(followsUserId) ? "已关注" : "已取关");
    }

    /**
     * 获取关注人员
     * @param basePage 分页信息
     * @param userId 用户id
     * @return
     */
    @GetMapping("/follows")
    public Result getFollows(BasePage basePage, Long userId) {
        log.info("{}获取关注人员", userId);
        return Result.ok().data(userService.getFollows(basePage, userId));
    }

    /**
     * 获取粉丝
     * @param basePage 分页信息
     * @param userId 用户id
     * @return
     */
    @GetMapping("/fans")
    public Result getFans(BasePage basePage, Long userId) {
        log.info("{}获取粉丝", userId);
        return Result.ok().data(userService.getFans(basePage, userId));
    }

    /**
     * 用户订阅或取消订阅分类
     * @param types 类型id，如：13,14,15
     * @return
     */
    @PostMapping("/subscribe")
    public Result subscribe(@RequestParam(name = "types", required = false) String types) {
        log.info("用户订阅或取消订阅分类");
        final HashSet<Long> typeIds = new HashSet<>();
        // 解析出被订阅的分类的id
        if (!ObjectUtils.isEmpty(types)) {
            for (String typeId : types.split(",")) {
                typeIds.add(Long.parseLong(typeId));
            }
        }
        userService.subscribe(typeIds);
        return Result.ok().message(MessageConstants.OPERATE_SUCCESS);
    }

    /**
     * 获取用户订阅的分类
     * @return
     */
    @GetMapping("/subscribe")
    public Result listSubscribeType() {
        log.info("获取用户订阅的分类");
        return Result.ok().data(userService.listSubscribeType(BaseContext.get()));
    }

    /**
     * 获取用户没有订阅的分类
     * @return
     */
    @GetMapping("/noSubscribe")
    public Result listNoSubscribeType() {
        log.info("获取用户没有订阅的分类");
        return Result.ok().data(userService.listNoSubscribeType(BaseContext.get()));
    }


    /**
     * 添加/修改收藏夹
     * @param favorites 收藏夹信息
     * @return
     */
    @PostMapping("/favorites")
    public Result saveOrUpdateFavorites(@RequestBody @Validated Favorites favorites) {
        log.info("添加或修改收藏夹");
        final Long userId = BaseContext.get();
        final Long id = favorites.getId(); // 提前保存收藏夹信息中的id，如果是null那就是添加操作，不是null那就是修改操作
        favorites.setUserId(userId);
        final int count = favoritesService.count(new LambdaQueryWrapper<Favorites>()
                .eq(Favorites::getName, favorites.getName())
                .eq(Favorites::getUserId, userId)
                .ne(Favorites::getId, id));
        if (count == 1) {
            return Result.error().message("已存在相同名称的收藏夹");
        }
        favoritesService.saveOrUpdate(favorites);
        return Result.ok().message(id != null ? "修改成功" : "添加成功");
    }

    /**
     * 删除收藏夹
     * @param id 收藏夹id
     * @return 返回操作结果
     */
    @DeleteMapping("/favorites/{id}")
    public Result deleteFavorites(@PathVariable Long id) {
        log.info("删除收藏夹：{}", id);
        favoritesService.remove(id, BaseContext.get());
        return Result.ok().message(MessageConstants.DELETE_SUCCESS);
    }

    /**
     * 获取所有收藏夹
     * @return 返回用户的所有收藏夹，包括收藏夹下的视频总数
     */
    @GetMapping("/favorites")
    public Result getAllFavorites() {
        final Long userId = BaseContext.get();
        log.info("{}获取所有收藏夹", userId);
        List<Favorites> favorites = favoritesService.listByUserId(userId);
        return Result.ok().data(favorites);
    }

    /**
     * 获取指定收藏夹信息
     * @param id 收藏夹id
     * @return
     */
    @GetMapping("/favorites/{id}")
    public Result getFavoritesById(@PathVariable Long id) {
        log.info("获取收藏夹：{}", id);
        return Result.ok().data(favoritesService.getById(id));
    }

    /**
     * 修改用户推送模型
     * @param model 信息
     * @return
     */
    @PostMapping("/updateUserModel")
    public Result updateUserModel(@RequestBody Model model) {
        log.info("修改用户模型");
        final Double score = model.getScore();
        if (score == 1.0 || score == -0.5) {
            final List<String> labels = Arrays.asList(model.getLabel().split(","));
            final UserModel userModel = UserModel.buildUserModel(labels, model.getVideoId(), score);
            userService.updateUserModel(userModel);
        }
        return Result.ok();
    }

}
